package stool.juc.threadpool;

import java.util.concurrent.*;

/**
 * 1. 在创建了线程池后，开始等待请求。
 * 2. 当调用execute()方法添加一个请求任务时，线程池会做出如下判断:
 * 	2.1 如果正在运行的线程数量小于corePoolSize，那么马上创建线程运行这个任务;
 * 	2.2 如果正在运行的线程数量大于或等于corePoo1lSize，那么将这个任务放入队列;
 * 	2.3 如果这个时候队列满了且正在运行的线程数量还小于maximumPoolSize，那么还是要创建非核心线程立刻运行这个任务;
 * 	2.4 如果队列满了且正在运行的线程数量大于或等于maximumPoolSize，那么线程池会启动饱和拒绝策略来执行。
 * 3. 当一个线程完成任务时，它会从队列中取下一个任务来执行。
 * 4. 当一个线程无事可做超过一定的时间（keepAliveTime）时，线程会判断:
 * @author Felix YF Dong
 * @Description
 * @Date 2023/2/20
 */
public class CustomThreadPool {

    public static void main(String[] args) {
//        1、corePoolSize:线程池中的常驻核心线程数
//
//        2、maximumPoolSize:线程池中能够容纳同时执行的最大线程数，此值必须大于等于1
//
//        3、keepAliveTime:多余的空闲线程的存活时间当前池中线程数量超过corePoolSize时，当空闲时间达到keepAliveTime时，多余线程会被销毁直到只剩下corePoolSize个线程为止
//
//        4、unit: keepAliveTime的单位
//
//        5、workQueue:任务队列，被提交但尚未被执行的任务
//
//        6、threadFactory:表示生成线程池中工作线程的线程工厂，用于创建线程，一般默认的即可
//
//        7、handler:拒绝策略，表示当队列满了，并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时如何来拒绝请求执行的runnable的策略
        // maximumPoolSize=CPU核数+1
        int t=Runtime.getRuntime().availableProcessors();
        ExecutorService threadpool = new ThreadPoolExecutor(
                2,
                t + 1,
                2L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
//                new ThreadPoolExecutor.AbortPolicy());// RejectedExecutionException（默认）
//                new ThreadPoolExecutor.CallerRunsPolicy());// main 办理业务，回退给调用者
//                new ThreadPoolExecutor.DiscardPolicy());// 抛弃，允许丢失
                new ThreadPoolExecutor.DiscardOldestPolicy());// 抛弃等待最久的，允许丢失

        try {
            for (int i = 0; i <= 100; i++) {
                int finalI = i;
                threadpool.execute(() -> {
                    System.out.println(finalI + "~" + Thread.currentThread().getName() + " 办理业务");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadpool.shutdown();
        }

    }

}
